/** @file kernel.h
*	This file contains most of the typedefinitions and structs.
*	 It also contains some global variables and definitions.
*/
#ifndef KERNEL_H
#define KERNEL_H


// Debug option
//#define       _DEBUG

/*********************************************************/
/** Global variabels and definitions                     */
/*********************************************************/

#include <stdlib.h>


#ifdef texas_dsp

#define CONTEXT_SIZE    34-2 

#else

#define CONTEXT_SIZE    13 
#define STACK_SIZE      100
#endif

#define TRUE    1
#define FALSE   !TRUE

#define RUNNING 1
#define INIT    !RUNNING

#define FAIL    0
#define SUCCESS 1
#define OK              1

#define DEADLINE_REACHED        -1
#define NOT_EMPTY               0

#define SENDER          +1
#define RECEIVER        -1

#define READYLISTTYPE = 1;
#define WAITINGLISTTYPE = 1;
#define TIMERLISTTYPE = -1;

typedef int             exception;
typedef int             bool;
typedef unsigned int    uint;
typedef int 			action;

struct  l_obj;         // Forward declaration


// Task Control Block, TCB
#ifdef texas_dsp
typedef struct
{
	void	(*PC)(); // Program counter
	uint	*SP; // Stack pointer
	uint	Context[CONTEXT_SIZE]; // TCB Context
	uint	StackSeg[STACK_SIZE]; // TCB stack
	uint	DeadLine; //The deadline of the TCB
} TCB;

#else
/** Task Control Block contains the neccessary tools for handling a task. */
typedef struct _TCB
{
        uint          Context[CONTEXT_SIZE];  
        uint         *SP; //Stack pointer, point to the top of the stack
        void         (*PC)(); //Program counter
        uint          SPSR; //saved programs start register
        uint          StackSeg[STACK_SIZE];
        uint          DeadLine;
	bool	      IsResumed;
        struct l_obj  *pLObj;
} TCB;
#endif

// Message items
typedef struct msgobj 
{
        char            *pData;
        exception       Status;
        struct l_obj    *pBlock;
        struct msgobj   *pPrevious;
        struct msgobj   *pNext;
} msg;

// Mailbox structure
typedef struct {
        msg             *pHead;
        msg             *pTail;
        int             nDataSize;
        int             nMaxMessages;
        int             nMessages;
        int             nBlockedMsg;
} mailbox;


// Generic list item
typedef struct l_obj {
         TCB            *pTask;
         uint           nTCnt;
         msg            *pMessage;
         struct l_obj   *pPrevious;
         struct l_obj   *pNext;
} listobj;

// Generic list
typedef struct _list
{
         listobj        *pHead;
         listobj        *pTail;
} list;


// Function prototypes


// Task administration
/** 
*/
int             init_kernel(void);
exception       create_task( void (* body)(), uint deadline );
void            terminate( void );
void            run( void );

// Communication
/**  */
mailbox*        create_mailbox(int nof_msg, int size_of_msg);
int             no_messages( mailbox* mBox );

exception       send_wait( mailbox* mBox, void* pData );
exception       receive_wait( mailbox* mBox, void* pData );

exception	send_no_wait( mailbox* mBox, void* pData );
int             receive_no_wait( mailbox* mBox, void* pData );


// Timing
exception	wait( uint nTicks );
void            set_ticks( uint no_of_ticks );
uint            getTicks( void );
uint		deadline( void );
void            set_deadline( uint nNew );

//Interrupt
extern void     isr_off(void);
extern void     isr_on(void);
extern void     SaveContext( void );	// Stores DSP registers in TCB pointed to by Running
extern void     LoadContext( void );	// Restores DSP registers from TCB pointed to by Running

#endif
